#include "../../mqserver/routing.hpp"
#include <gtest/gtest.h>

class RoutingTest : public testing::Environment
{
public:
    // 初始化
    virtual void SetUp() override
    {
        
    }

    virtual void TearDown() override
    {
        // 清理队列操作
        // msgQueues->clear();
        std::cout << "执行真正数据库清理操作" << std::endl;
    }
};

//合法性测试
TEST(RoutingTest,legal_test)
{
    //routing key
    std::string rstr1 = "1234aaa.Ac.__ass__..."; //普通

    std::string rstr2 = "1234aaa.Ac.__ass__.*."; //其他字符
    std::string rstr3 = "1234aaa.Ac.__ass__.#.";
    std::string rstr4 = "1234aaa.Ac.__ass__.>.";

    std::string rstr5 = "1234aaa.Ac.__ass__.22.";//普通
    std::string rstr6 = "1234aaa.Ac.__ass__..44";



    LOG(logLevel::DEBUG) << MyRabbitMQ::Router::isLegalRoutingKey(rstr1) << std::endl;
    LOG(logLevel::DEBUG) << MyRabbitMQ::Router::isLegalRoutingKey(rstr2) << std::endl;
    LOG(logLevel::DEBUG) << MyRabbitMQ::Router::isLegalRoutingKey(rstr3) << std::endl;
    LOG(logLevel::DEBUG) << MyRabbitMQ::Router::isLegalRoutingKey(rstr4) << std::endl;
    LOG(logLevel::DEBUG) << MyRabbitMQ::Router::isLegalRoutingKey(rstr5) << std::endl;
    LOG(logLevel::DEBUG) << MyRabbitMQ::Router::isLegalRoutingKey(rstr6) << std::endl;

    //binding key
    std::string bstr1 = "1234aaa.Ac.__ass__..."; //普通
    std::string bstr2 = "1234aaa.Ac.__ass__.*."; 
    std::string bstr3 = "1234aaa.Ac.__ass__.#.";

    
    std::string bstr4 = "1234aaa.Ac.__ass__.>.";
    std::string bstr5 = "1234aaa.Ac.__ass__.*.#.";
    std::string bstr6 = "1234aaa.Ac.__ass__.#.*";
    std::string bstr7 = "1234aaa.Ac.__ass__.#.#";
    std::string bstr8 = "1234aaa.Ac.__ass__.*1.*2";
    std::string bstr9 = "1234aaa.Ac.__ass__.1*.3*";
    std::string bstr10 = "1234aaa.Ac.__ass__.1#.*";


    std::string bstr11 = "1234aaa.Ac.__ass__.*.*";
    
    LOG(logLevel::DEBUG) << MyRabbitMQ::Router::isLegalBindingKey(bstr1) << std::endl;
    LOG(logLevel::DEBUG) << MyRabbitMQ::Router::isLegalBindingKey(bstr2) << std::endl;
    LOG(logLevel::DEBUG) << MyRabbitMQ::Router::isLegalBindingKey(bstr3) << std::endl;
    LOG(logLevel::DEBUG) << MyRabbitMQ::Router::isLegalBindingKey(bstr4) << std::endl;
    LOG(logLevel::DEBUG) << MyRabbitMQ::Router::isLegalBindingKey(bstr5) << std::endl;
    LOG(logLevel::DEBUG) << MyRabbitMQ::Router::isLegalBindingKey(bstr6) << std::endl;
    LOG(logLevel::DEBUG) << MyRabbitMQ::Router::isLegalBindingKey(bstr7) << std::endl;
    LOG(logLevel::DEBUG) << MyRabbitMQ::Router::isLegalBindingKey(bstr8) << std::endl;
    LOG(logLevel::DEBUG) << MyRabbitMQ::Router::isLegalBindingKey(bstr9) << std::endl;
    LOG(logLevel::DEBUG) << MyRabbitMQ::Router::isLegalBindingKey(bstr10) << std::endl;
    LOG(logLevel::DEBUG) << MyRabbitMQ::Router::isLegalBindingKey(bstr11) << std::endl;
}


TEST(RoutingTest, route_test) {
// aaa                  aaa                     true
// aaa.bbb              aaa.bbb                 true
// aaa.bbb              aaa.bbb.ccc             false
// aaa.bbb              aaa.ccc                 false
// aaa.#.bbb            aaa.bbb.ccc             false
// aaa.bbb.#            aaa.ccc.bbb             false
// #.bbb.ccc            aaa.bbb.ccc.ddd         false
// aaa.bbb.ccc          aaa.bbb.ccc             true
// aaa.*                aaa.bbb                 true
// aaa.*.bbb            aaa.bbb.ccc             false
// *.aaa.bbb            aaa.bbb                 false
// #                    aaa.bbb.ccc             true
// aaa.#                aaa.bbb                 true
// aaa.#                aaa.bbb.ccc             true
// aaa.#.ccc            aaa.ccc                 true
// aaa.#.ccc            aaa.bbb.ccc             true
// aaa.#.ccc            aaa.aaa.bbb.ccc         true
// #.ccc                ccc                     true
// #.ccc                aaa.bbb.ccc             true
// aaa.#.ccc.ccc        aaa.bbb.ccc.ccc.ccc     true
// aaa.#.bbb.*.bbb      aaa.ddd.ccc.bbb.eee.bbb true

    std::vector<std::string> bkeys = {
        "aaa",
        "aaa.bbb",
        "aaa.bbb", 
        "aaa.bbb",
        "aaa.#.bbb",
        "aaa.bbb.#",
        "#.bbb.ccc",
        "aaa.bbb.ccc",
        "aaa.*",
        "aaa.*.bbb",
        "*.aaa.bbb", 
        "#",   
        "aaa.#", 
        "aaa.#",  
        "aaa.#.ccc",
        "aaa.#.ccc",
        "aaa.#.ccc",
        "#.ccc",
        "#.ccc",
        "aaa.#.ccc.ccc",
        "aaa.#.bbb.*.bbb"
    };

    std::vector<std::string> rkeys = {
        "aaa",
        "aaa.bbb",    
        "aaa.bbb.ccc",        
        "aaa.ccc",        
        "aaa.bbb.ccc",        
        "aaa.ccc.bbb",        
        "aaa.bbb.ccc.ddd",    
        "aaa.bbb.ccc",       
        "aaa.bbb",         
        "aaa.bbb.ccc",      
        "aaa.bbb",         
        "aaa.bbb.ccc",       
        "aaa.bbb",        
        "aaa.bbb.ccc",     
        "aaa.ccc",        
        "aaa.bbb.ccc",       
        "aaa.aaa.bbb.ccc",  
        "ccc",         
        "aaa.bbb.ccc",    
        "aaa.bbb.ccc.ccc.ccc",
        "aaa.ddd.ccc.bbb.eee.bbb"
    };
    std::vector<bool> result = {
        true,
        true,
        false,
        false,
        false,
        false,
        false,
        true,
        true,
        false,
        false,
        true,
        true,
        true,
        true,
        true,
        true,
        true,
        true,
        true,
        true
    };

    for (int i = 0; i < bkeys.size(); i++) {
        ASSERT_EQ(MyRabbitMQ::Router::route(protoMQ::ExchangeType::tpoic, rkeys[i], bkeys[i]), result[i]);
        std::cout << rkeys[i] << "与" << bkeys[i] << "配对结果为" << result[i] << std::endl;
    }
}

int main(int argc, char *argv[])
{
    testing::InitGoogleTest(&argc, argv);
    testing::AddGlobalTestEnvironment(new RoutingTest);
    int ret = RUN_ALL_TESTS();
    return 0;
}